//unordered_map容器
//这个容器封装了哈希表,哈希表就是数组与链表的结合，
// 每一个数组称为桶，每个桶是一个链表
//unordered_map大多数功能和map容器一样，
#include<iostream>
#include<unordered_map>//头文件
#include<string>
using namespace std;


template<class K, class V>
using umap = std::unordered_map<K, V>;	//umap别名
//umap.max_load_factor()	//显示容器最大装填因子（元素个数/桶数）(缺省为1)
//umap.bucket_count()	//显示当前桶数(缺省为8),当装填因子超过最大装填因子时，桶数会自动扩展
//umap.load_factor()	//当前装填因子
//umap扩容会将全部已分配的数组和链表销毁，重新哈希，代价非常大
//umap.end(n)	//返回第n个桶最后一个元素的迭代器
//umap.begin(n)	//返回第n个桶第一个元素的迭代器
//umap.reserve(n)	//将容器设置为n个桶
//umap.rehash(n)	//将桶的数量调整为>=n, 若本来桶数就比n大，无事发生；若比n小，则重新哈希分配为n个桶
//umap.bucket_size(n)	//返回第n个桶中元素个数
//umap.bucket(key)	//返回值为key的元素对应的桶的编号
int main()
{
	umap<int, string> m1;	//创建一个空的umap容器

	umap<int, string> m2({ {8, "孙悟空"}, {5,"猪悟能"}, {9, "沙悟净"},{12, "唐三藏"} });

	for (auto val : m2)
	{
		cout << val.first << ", " << val.second << " " << endl;
	}
	
	m1.max_load_factor(5);	//设置最大填充因子，避免扩容
	for(int i=0; i<20; i++)
	{
		//string tmp = ("小明" + i + '0');
		m1.emplace(i, "小明");		//emplace()会自动变成pair形式
	}
	//遍历方式一：
	for (auto it = m1.begin(); it != m1.end(); it++)		
	{	
		cout << it->first << ", " << it->second << endl;
	}

	//遍历方式二:
	for (int ii = 0; ii < m1.bucket_count(); ii++)
	{
		cout << "桶" << ii << ": ";
		for (auto it = m1.begin(ii); it != m1.end(ii); it++)
		{
			cout << it->first << ", " << it->second << " ";
		}
		cout << endl;
	}

	for (int ii = 0; ii < m1.bucket_count(); ii++)
	{
		cout << "桶" << ii << "有 " << m1.bucket_size(ii) << " 个元素。" << endl;
	}
	return 0;
}










//unordered_set容器
//unordered_set是一个使用哈希表实现的集合（set）容器，用于存储唯一的元素，且元素的存储没有特定的顺序。unordered_set使用哈希函数来将元素映射到桶中，不同的元素可能映射到同一个桶中，但是这些元素的哈希值不同。
//相较于unordered_map,unordered_set与之的区别是:
/*
	1.存储元素的方式：unordered_map 存储键值对，而 unordered_set 只存储键，没有值。
	2.元素的唯一性：unordered_map 中每个键只能对应一个值，而 unordered_set 中每个键只能出现一次。
	3.元素的访问：unordered_map 可以通过键来访问值，而 unordered_set 只能通过键来判断元素是否存在。
	4.内部实现：unordered_map 和 unordered_set 都是使用哈希表实现的，但是 unordered_map需要同时保存键和值，因此在内部实现上需要比 unordered_set 多一些开销。
*/


unordered_set<int> myset = {1, 2, };		//定义哈希集合

myset.insert(3);							//哈希集合插入元素

auto it = myset.find(2);					//查找元素，返回迭代器
if(it!=myset.end())
	cout << ""<<*it<<"在myset内" << endl;

myset.erase(2);			//删除元素

int num = myset.size();		//返回哈希表中元素个数

bool tmp = myset.empty();	//检查是否为空

myset.clear();				//清空哈希表

int num_3 = myset.count(3);	//返回元素3的个数，由于unordered_set不允许重复，所以要么返回1要么返回0
							//一般用于检验哈希表中是否有该元素
							//而unordered_multiset就可以返回具体个数


//还有unordered_multiset容器，与unordered_set的区别是，unordered_multiset看可以同时存储多个相同的元素
//unordered_set存储元素不允许重复
